#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
#
# This file is part of Coruja-scripts
#
# Coruja-scripts is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# Coruja-scripts is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Coruja-scripts.  If not, see <http://www.gnu.org/licenses/>.
#
# Copyright 2011 Grupo Falabrasil - http://www.laps.ufpa.br/falabrasil
#
# Author 2011: Pedro Batista - pedosb@gmail.com

import argparse
import sys
import random
import numpy as np
from config import *
from dtw import dtw_distance
from vq import k_means
from HTKParameters import HTKParameters as hpm

from mpi4py import MPI
comm = MPI.COMM_WORLD
size = MPI.COMM_WORLD.Get_size()
rank = MPI.COMM_WORLD.Get_rank()
name = MPI.Get_processor_name()

def get_tamplates(word_list=config.get('files', 'word_list'),
		train_mask_prefix=config.get('files', 'train_mask_prefix'),
		train_mask_suffix=config.get('files', 'train_mask_suffix'),
		template=config.get('files', 'template')):
	if rank == 0:
		l = [l.strip() for l in open(word_list).readlines()]
		random.shuffle(l)
	else:
		l = None
	l = comm.bcast(l, root=0)
	m = len(l) / size
	resto = len(l) - m * size
	s = rank * m + (rank if rank < resto else resto)
	l = l[s : s + m + (1 if rank < resto else 0)]
	t = []
	for word in l:
		train_file_list = train_mask_prefix + word + train_mask_suffix
		codebook = k_means([hpm(l.strip()) for l in open(train_file_list)])
		t += [i._file.name for i in codebook.code_word_list]
	if rank == 0:
		for i in xrange(1, size):
			t += comm.recv(source=i, tag=i)
		out = open(template, 'w')
		out.write('\n'.join(t))
		out.close()
	else:
		comm.send(t, dest=0, tag=rank)

def file_len(fname):
	"""
	http://stackoverflow.com/questions/845058/how-to-get-line-count-cheaply-in-python
	"""
	with open(fname) as f:
		for i, l in enumerate(f):
			pass
	return i + 1

def centroid(file_list):
	f = open(file_list)
	l = [l.strip() for l in f.readlines()]
	s = len(l)
	d = np.zeros(2 * [s])
	t = (s ** 2 - s) / 2.0
	p = 0
	for i in xrange(s):
		for j in xrange(i+1, s):
			d[i, j] = dtw_distance(l[i], l[j])
			p += 1
			sys.stderr.write('\r%6.2f%%' % ((p / t) * 100))
			sys.stderr.flush()
	sys.stderr.write('\n')
	d += d.transpose()
	c_sum = d.sum(0)
	return l[c_sum.argmin()]

if __name__=='__main__':
	parser = argparse.ArgumentParser(description='Compute the centroid of a set of files.')
#	parser.add_argument('-f', '--file-list', required=True,
#		help='Text file containing one parameter file name by line.')
#	print centroid(args.file_list)
#	parser.add_argument('-c', '--config-file', default='',
#		help='A specific config file')
	args = parser.parse_args()
	get_tamplates()
